﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MugenInjection;
using MugenInjection.Infrastructure;
using MugenInjection.Interface;
using MugenInjection.Interface.Components;
using MugenInjection.Wcf.Interface;
using MugenInjection.Web;
using MugenInjection.Web.Interface;
using MugenInjectionTest.Core;
using Should;

namespace MugenInjectionTest.Web.Wcf
{
    [TestClass]
    public class WcfApplicationInit : TestBase
    {
        [TestInitialize]
        public void TestCleanup()
        {
            MugenInjectionHttpApplication.ApplicationConfiguration = null;
        }


        [TestMethod]
        public void TestInitEmptyApp()
        {
            var mvc = new WcfApplication();
            TestUtils.Catch<NullReferenceException>(() => MugenInjectionHttpApplication.ApplicationConfiguration.ToString());
            TestUtils.Catch<NullReferenceException>(() => MugenInjectionHttpApplication.ApplicationConfiguration.Injector.Settings.AttributeForInject.ToString());

            using (var mugenInjector = GetInjector())
            {
                //Empty configuration
                mvc.ApplicationConfig = configuration =>
                {

                };
                mvc.InjectorFunc = () => mugenInjector;
                mvc.Application_Start();
                MugenInjectionHttpApplication.ApplicationConfiguration.ShouldNotBeNull();
                MugenInjectionHttpApplication.ApplicationConfiguration.Injector.ShouldEqual(mugenInjector);

                TestUtils.Catch<NotSupportedException>(() => mugenInjector.Bind<WcfApplication>().ToSelf().InSessionScope());
                TestUtils.Catch<NotSupportedException>(() => mugenInjector.Bind<WcfApplication>().ToSelf().InHttpRequestScope());
                TestUtils.Catch<NotSupportedException>(() => mugenInjector.Bind<WcfApplication>().ToSelf().InOperationRequestScope());
                TestUtils.Catch<MugenInjection.Exceptions.BindingNotFoundException>(() => mugenInjector.Get<IServiceBehavior>());
                TestUtils.Catch<MugenInjection.Exceptions.BindingNotFoundException>(() => mugenInjector.Get<IDispatchMessageInspector>());
            }
        }

        [TestMethod]
        public void TestInitWcfApp()
        {
            var mvc = new WcfApplication();
            TestUtils.Catch<NullReferenceException>(() => MugenInjectionHttpApplication.ApplicationConfiguration.ToString());

            using (var mugenInjector = GetInjector())
            {
                IApplicationConfiguration configurationGlobal = null;
                //Empty configuration
                mvc.ApplicationConfig = configuration =>
                {
                    configurationGlobal = configuration;
                    configuration.WithWcfConfiguration().WithHttpConfiguration();
                };
                mvc.InjectorFunc = () => mugenInjector;
                mvc.Application_Start();
                MugenInjectionHttpApplication.ApplicationConfiguration.ShouldEqual(configurationGlobal);
                MugenInjectionHttpApplication.ApplicationConfiguration.Injector.ShouldEqual(mugenInjector);

                MugenInjectionHttpApplication.ApplicationConfiguration.Configurations.Count.ShouldEqual(2);
                mugenInjector.Bind<WcfApplication>().ToSelf().InSessionScope();
                mugenInjector.Bind<WcfApplication>().ToSelf().InHttpRequestScope();
                mugenInjector.Bind<WcfApplication>().ToSelf().InOperationRequestScope();

                var messageInspector1 = mugenInjector.Components.Get<IBehaviorManagerComponent>().Get<IDispatchMessageInspector>();
                var messageInspector2 = mugenInjector.Components.Get<IBehaviorManagerComponent>().Get<IDispatchMessageInspector>();
                messageInspector1.ShouldNotBeNull();
                messageInspector1.ShouldEqual(messageInspector2);
            }
        }
    }

    public class WcfApplication : MugenInjectionHttpApplication
    {
        #region

        public Func<IInjector> InjectorFunc { get; set; }
        public Action<IApplicationConfiguration> ApplicationConfig { get; set; }

        #endregion

        #region Overrides of MugenInjectionHttpApplication

        /// <summary>
        /// Creates the injector that will manage your application.
        /// </summary>
        /// <returns>The created injector.</returns>
        protected override IInjector CreateInjector()
        {
            return InjectorFunc();
        }

        /// <summary>
        /// Configure current <see cref="MugenInjectionHttpApplication"/>
        /// </summary>
        /// <param name="applicationConfiguration">Configuration instance.</param>
        protected override void Configure(IApplicationConfiguration applicationConfiguration)
        {
            ApplicationConfig(applicationConfiguration);
        }

        #endregion
    }
}
